#include "ring.h"

#define MAX_STRING 100

void ring(int nb_procs, int nb_messages){

  if(nb_procs < 2){
    ecrire("You need at least two processes to have a ring !\n");
    quitter(FAILURE);
  }

  if(nb_messages < 1){
    ecrire("We should pass at least one message, don't you think?\n");
    quitter(FAILURE);
  }

  int32_t* node_pids = allouer(nb_procs*sizeof(int));
  if(node_pids == NULL){
    ecrire("Out of memory\n");
    quitter(FAILURE);
  }
  int32_t args[4] = {0,0,0,0};
  int i,j,status;
  char buf[100];
  char s[4];
  args[1] = nb_messages;

  /* fork the NUM_PROCS children */
  for(i=0; i < nb_procs; i++){ 
    args[0] = i; //id of this node
    node_pids[i] = fourchette(32, "ring_node", args);
    if(node_pids[i] < 0){
      ecrire("A problem occured when creating the processes. Clean-up started\n");
      for(j=0;j<i;j++)
        tuer(node_pids[j],FAILURE);
      ecrire("Clean-up done. Exit\n");
      quitter(FAILURE);
    }
    strncpy(buf,"created process: ",MAX_STRING);
    strncat(buf,itoa((int)(node_pids[i]), s, 4),MAX_STRING-strlen(s));
    strncat(buf,"\n",MAX_STRING-strlen(s));
    ecrire(buf);
  }

  /* set up the nodes with the id of the next node */
  for(i=0; i < nb_procs; i++) {
    envoyer_entier(node_pids[i], node_pids[(i+1)%nb_procs], 9);
    strncpy(buf,"Sending next_node_pid to process: ",MAX_STRING);
    strncat(buf,itoa((int)(node_pids[i]), s, 4),MAX_STRING-strlen(s));
    strncat(buf,"\n",MAX_STRING-strlen(s));
    ecrire(buf);
  }

  /* make the control node start */
  envoyer_chaine(node_pids[nb_procs-1], "Initial message", 9);

  /* die and let the nodes do their thing */
  ecrire("Parent will now wait for its children\n");
  for(i=0;i<nb_procs;i++)
    attendre(node_pids[i],&status);
  ecrire("Children have stopped, program terminated.\n");
  quitter(SUCCESS);
}
